import dayjs from "dayjs";
import { useAtomValue } from "jotai";
import { useEffect, useState } from "react";
import Chart, { useEchartsInstance } from "@/components/Chart";
import { getDeviceChartHistory } from "@/lib/api/deviceStatus";
import useFetch from "@/lib/hooks/useFetch";
import { useWebSocket } from "@/providers/WebsocketProvider";
import { tokenAtom } from "@/store/user";

type RealtimeOverviewChartProps = {
  deviceId: number;
};

export default function RealtimeOverviewChart(
  props: RealtimeOverviewChartProps,
) {
  const { deviceId } = props;
  const [chartData, setChartData] = useState<echarts.EChartsOption | null>(
    null,
  );
  const { websocket } = useWebSocket();
  const token = useAtomValue(tokenAtom);
  const echarts = useEchartsInstance();

  const { refetch: loadChartRealtime, cancel: cancelLoadChartRealtime } =
    useFetch({
      fetchFn: async (deviceId: number, signal: AbortSignal) => {
        const now = new Date();
        return getDeviceChartHistory(
          {
            deviceId,
            interval: 5,
            startTime: dayjs(now).add(-2, "hour").format("YYYY-MM-DD HH:mm:ss"),
            endTime: dayjs(now).format("YYYY-MM-DD HH:mm:ss"),
          },
          token,
          signal,
        ).then((res) => {
          if (res.code !== 200) {
            throw res;
          }
          return res.data;
        });
      },
      onSuccess(data) {
        // console.log(data);
        // data.yAxis = { show: false, splitLine: { show: false } };
        data.xAxis = (data.xAxis as any)[0];
        data.series = (data.series as any[]).map((item) => {
          delete item.yAxisId;
          return item;
        });
        data.grid = { top: "10%", bottom: "10%" };
        setChartData(data as echarts.EChartsOption);
        websocket.emit("BEGIN_CHARTS", { deviceId });
      },
    });

  useEffect(() => {
    function onData(data: [string, string, ...number[]]) {
      setChartData((p) => updateChartData(p, data));
    }
    websocket.on("CHARTS_ON_TIME", onData);
    return () => {
      websocket.off("CHARTS_ON_TIME", onData);
    };
  }, []);

  useEffect(() => {
    loadChartRealtime(deviceId);

    return () => {
      cancelLoadChartRealtime();
      setChartData(null);

      websocket.emit("END_CHARTS");
    };
  }, [deviceId]);

  return (
    <div className="mb-16 mt-6 h-[400px]">
      <Chart className="h-full" options={chartData} echarts={echarts} />
    </div>
  );
}

function updateChartData(options: any, data: [string, string, ...number[]]) {
  const [time, _, ...value] = data;
  const xAxisData = options.xAxis.data.concat(time) as string[];
  const seriesData = (options.series as any[]).map((item, index) => [
    ...item.data,
    value[index],
  ]);
  while (
    xAxisData.length > 2 &&
    new Date(xAxisData.at(-1)!).getTime() -
      new Date(xAxisData.at(0)!).getTime() >
      7200000 // 2 hour
  ) {
    xAxisData.shift();
    seriesData.forEach((item) => {
      item.splice(0, 1);
    });
  }
  return {
    ...options,
    xAxis: {
      ...options.xAxis,
      data: xAxisData,
    },
    series: options.series.map((item: any, index: number) => ({
      ...item,
      data: seriesData[index],
    })),
  };
}
